Skip to content

feat: NSMul/NPow type class#38036

Open
JovanGerb wants to merge 13 commits intoleanprover-community:masterfrom
JovanGerb:Jovan-NSMul
Open

feat: NSMul/NPow type class#38036
JovanGerb wants to merge 13 commits intoleanprover-community:masterfrom
JovanGerb:Jovan-NSMul

Conversation

@JovanGerb
Copy link
Copy Markdown
Contributor

@JovanGerb JovanGerb commented Apr 14, 2026

This PR is adds NSMul, NPow, ZSMul and ZPow classes for the nsmul, npow, zsmul, zpow data fields.

This has a few advantages:

  • If you first declare a SMul instance, then you don't need to manually write nsmul := (· • ·) and zsmul := (· • ·) . For Pow, the extra benefit is that inferring the instance is preferred over the default field npowRecAuto. So this helps avoid accidental diamonds.
  • If you first declare a SMul instance on a type synonym, then inferInstanceAs will infer the nsmul field from the SMul instance. This makes it easier to avoid diamonds on type synonyms like Matrix and MonoidAlgebra.
  • The not-yet-merged instance diamond linter will be able to detect cases where the NSMul and SMul classes do not agree.

In the process of making this PR, I have identified two existing NPow diamonds:

  • In Mathlib.Algebra.Order.Positive.Field, there were two conflicting NPow instances.
  • For Fin, there are two conflicting NPow instances. I have overwritten the one in core lean with the one from mathlib that is more computationally efficient.

TODO: the same for QSMul and NNQSMul.


Open in Gitpod

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 14, 2026

PR summary 044631201f

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference

Declarations diff

+ NPow
+ NPow.ofPow
+ NPow.toPow
+ NSMul
+ ZPow
+ ZPow.ofPow
+ ZPow.toPow
+ ZSMul
+ instance (n : ℕ) [NeZero n] : HPow (Fin n) ℕ (Fin n)
+ instance (n : ℕ) [NeZero n] : Pow (Fin n) ℕ
+ instance {A : Type*} [SMulZeroClass A R] : SMul A R[M]
- DivInvMonoid.toZPow
- Monoid.toPow
- SubNegMonoid.toZSMul
-++- addGroup

You can run this locally as follows
## summary with just the declaration names:
./scripts/pr_summary/declarations_diff.sh <optional_commit>

## more verbose report:
./scripts/pr_summary/declarations_diff.sh long <optional_commit>

The doc-module for scripts/pr_summary/declarations_diff.sh contains some details about this script.


Decrease in tech debt: (relative, absolute) = (1.04, 0.03)
Current number Change Type
6395 1 backward.isDefEq.respectTransparency
803 -2 backward.privateInPublic
414 -1 backward.privateInPublic.warn
46 -1 dsimp +instances

Current commit 12eaeeacf4
Reference commit 044631201f

You can run this locally as

./scripts/reporting/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@JovanGerb JovanGerb added the WIP Work in progress label Apr 14, 2026
@eric-wieser
Copy link
Copy Markdown
Member

Could you elaborate on the benefit here?

@eric-wieser
Copy link
Copy Markdown
Member

  • If you first declare a SMul instance, then you don't need to manually write nsmul := (· • ·) and zsmul := (· • ·) .

This can also be achieved with [toNatSMul : SMul Nat A] as a field.

@JovanGerb
Copy link
Copy Markdown
Contributor Author

JovanGerb commented Apr 14, 2026

Sure, but then you lose the ability to write nsmul := ..., and instead you have to write some awkward toNSMul := ⟨...⟩

⟨fun x n ↦ NPow.npow n x⟩

@[to_additive ofSMul]
instance NPow.ofPow {M : Type*} [Pow M ℕ] : NPow M := ⟨fun n x ↦ x ^ n⟩
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this desirable? Shouldn't we just assume that any Pow M ℕ instance already comes from NPow M?

@[to_additive] instance addCommMonoid : AddCommMonoid R[M] :=
fast_instance% { (inferInstance : AddCommMonoid <| M →₀ R) with
nsmul n x := x.mapRange (n • ·) (smul_zero _) }
inferInstanceAs <| AddCommMonoid <| M →₀ R
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happened to fast_instance%?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the great thing: inferInstanceAs will automatically fill in the nsmul field using the smul that was was declared above. (Recall that inferInstanceAs and fast_instance% do the same kind of instance normalization). Previously, we had to awkwardly declare the nsmul field in order to avoid diamond.

I think this should also answer your other question: yes we do need to infer NSMul instances from SMul instances, for example here.

@JovanGerb
Copy link
Copy Markdown
Contributor Author

!bench

@leanprover-radar
Copy link
Copy Markdown

leanprover-radar commented Apr 15, 2026

Benchmark results for 12eaeea against 0446312 are in. There are significant results. @JovanGerb

  • 🟥 build//instructions: +319.8G (+0.19%)

Large changes (1✅, 4🟥)

  • 🟥 build/module/Mathlib.Analysis.CStarAlgebra.Fuglede//instructions: +20.8G (+40.83%)
  • 🟥 build/module/Mathlib.Analysis.SpecialFunctions.Log.Deriv//instructions: +9.1G (+13.23%)
  • 🟥 build/module/Mathlib.CategoryTheory.Triangulated.TriangleShift//instructions: +39.1G (+21.23%)
  • 🟥 build/module/Mathlib.NumberTheory.Harmonic.GammaDeriv//instructions: +8.4G (+23.20%)
  • build/module/Mathlib.RingTheory.Polynomial.UniversalFactorizationRing//instructions: -47.0G (-16.88%)

Medium changes (16✅, 10🟥)

Too many entries to display here. View the full report on radar instead.

Small changes (39✅, 69🟥)

Too many entries to display here. View the full report on radar instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

WIP Work in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants